package com.tarim.streetdance.api;

import com.alibaba.fastjson.JSONObject;
import com.tarim.streetdance.model.PasswordRecord;
import com.tarim.streetdance.model.User;
import com.tarim.streetdance.service.PasswordRecordService;
import com.tarim.streetdance.service.UserService;
import com.tarim.streetdance.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@CrossOrigin
@RequestMapping("/api/user")
public class UserApi {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserService service;
    @Autowired
    private PasswordRecordService passwordRecordService;

    TokenProccessor tokenProccessor = TokenProccessor.getInstance();

    /*static String imagePath = "/Users/l2day/Documents/毕设/任建衡-高校街舞宣传/file/";
    static String fileUrl = "http://localhost/static/";*/

    static String imagePath = "/data/file/streedance/";
    static String fileUrl = "http://123.56.87.55/static/streedance/";

    /**
     * 用户注册
     * @param user
     * @return
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public JsonResult insert(User user){
        JsonResult jsonResult;
        try {
            List<User> users = service.selectByCondition(user);
            if (users != null && users.isEmpty()) {
                String userCode = user.getUserCode();
                if (userCode.length() < 3 || userCode.length() > 16) {
                    jsonResult = new JsonResult(Constants.STATUS_FAIL, "用户名由3-16位字符组成");
                    return jsonResult;
                }
                String password = AesEncryptUtil.desEncrypt(user.getPassword());
                if (password.length() < 6 || password.length() > 16){
                    jsonResult = new JsonResult(Constants.STATUS_FAIL, "密码由6-16位字符组成，区分大小写");
                    return jsonResult;
                }
                user.setPassword(AesEncryptUtil.encrypt(MD5Utils.MD5(password)));
                User user1 = service.insertSelective(user);
                jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "注册成功");
            }else {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "用户名已存在");
            }
        }catch (Exception ex){
            ex.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "注册异常，请联系管理员");
        }
        return jsonResult;
    }

    /**
     * 登录
     * @param user
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public JsonResult login(HttpServletRequest request, HttpServletResponse response, User user){
        JsonResult jsonResult;
        String token = tokenProccessor.makeToken();
        try {
            Date now = new Date();
            User loginUser = service.selectForLogin(user);
            if (loginUser == null) {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "用户不存在");
                return jsonResult;
            }
            String password = AesEncryptUtil.desEncrypt(user.getPassword());
            User updateUser = new User();
            updateUser.setId(loginUser.getId());
            if (!loginUser.getPassword().equals(AesEncryptUtil.encrypt(MD5Utils.MD5(password)))){
                if (loginUser.getStatus() == 3) {
                    jsonResult = new JsonResult(Constants.STATUS_FAIL, "该账号已被封停！");
                    return jsonResult;
                }
                if (loginUser.getStatus() == 2) {
                    jsonResult = new JsonResult(Constants.STATUS_FAIL, "该账号已被锁定！");
                    return jsonResult;
                }
                if (loginUser.getLoginErrorNum() < 4) {
                    Integer loginErrorNum = loginUser.getLoginErrorNum() + 1;
                    updateUser.setLoginErrorNum(loginErrorNum);
                    service.updateByPrimaryKeySelective(updateUser);
                    jsonResult = new JsonResult(Constants.STATUS_FAIL, "用户名密码错误,再错误"+(4-loginUser.getLoginErrorNum())+"次账号将被锁定!");
                }else {
                    Integer loginErrorNum = loginUser.getLoginErrorNum() + 1;
                    updateUser.setLoginErrorNum(loginErrorNum);
                    if (loginErrorNum == 5) {
                        long time = 30*60*1000;//30分钟
                        Date afterDate = new Date(now.getTime() + time);
                        updateUser.setRelieveTime(afterDate);
                        updateUser.setStatus(2);
                    }
                    service.updateByPrimaryKeySelective(updateUser);
                    jsonResult = new JsonResult(Constants.STATUS_FAIL, "该账号已被锁定,解锁时间:"+DateFormatUtils.format(loginUser.getRelieveTime(), DateFormatUtils.DEFAULT_TIME_FORMAT));
                }
            }else {
                if (loginUser.getStatus() == 3) {
                    if (loginUser.getRelieveTime().getTime() > now.getTime()) {
                        jsonResult = new JsonResult(Constants.STATUS_FAIL, "该账号已被封停,解封时间:"+DateFormatUtils.format(loginUser.getRelieveTime(), DateFormatUtils.DEFAULT_TIME_FORMAT));
                    }else {
                        redisUtil.set(token, loginUser);
                        response.setHeader("token", token);
                        updateUser.setUserCode(loginUser.getUserCode());
                        updateUser.setStatus(0);
                        updateUser.setLoginErrorNum(0);
                        updateUser.setRelieveTime(null);
                        service.updateByPrimaryKeySelective(updateUser);
                        loginUser.setPassword(null);
                        jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "登录成功", loginUser);
                    }
                    return jsonResult;
                }
                if (loginUser.getStatus() == 2) {
                    if (loginUser.getRelieveTime().getTime() > now.getTime()) {
                        jsonResult = new JsonResult(Constants.STATUS_FAIL, "该账号已被锁定,解锁时间:"+DateFormatUtils.format(loginUser.getRelieveTime(), DateFormatUtils.DEFAULT_TIME_FORMAT));
                    }else {
                        redisUtil.set(token, loginUser);
                        response.setHeader("token", token);
                        updateUser.setUserCode(loginUser.getUserCode());
                        updateUser.setStatus(0);
                        updateUser.setLoginErrorNum(0);
                        updateUser.setRelieveTime(null);
                        service.updateByPrimaryKeySelective(updateUser);
                        loginUser.setPassword(null);
                        jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "登录成功", loginUser);
                    }
                    return jsonResult;
                }
                redisUtil.set(token, loginUser);
                response.setHeader("token", token);
                loginUser.setPassword(null);
                jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "登录成功", loginUser);
            }
        }catch (Exception e) {
            e.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "系统异常，请联系管理员");
        }
        return jsonResult;
    }

    /**
     * 登出
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/loginOut", method = RequestMethod.POST)
    public JsonResult loginOut (HttpServletRequest request, HttpServletResponse response) {
        JsonResult jsonResult;
        try {
            String token = request.getHeader("token");
            redisUtil.del(token);
            jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "已登出");
        }catch (Exception e) {
            e.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "系统异常，请联系管理员");
        }
        return jsonResult;
    }

    /**
     * 更新用户信息
     * @param request
     * @param response
     * @param user
     * @return
     */
    @RequestMapping(value = "/update")
    public JsonResult updateUser (HttpServletRequest request, HttpServletResponse response, User user) {
        JsonResult jsonResult;
        try {
            String token = request.getHeader("token");
            Object object = redisUtil.get(token);
            if (object == null) {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "暂未登录账号");
                return jsonResult;
            }
            JSONObject jsonObject = (JSONObject) object;
            User user1 = jsonObject.toJavaObject(User.class);
            if (user1.getId() == user.getId()) {
                int i = service.updateByPrimaryKeySelective(user);
                User user2 = service.selectByPrimaryKey(user1.getId());
                redisUtil.del(token);
                redisUtil.set(token, user2);
                user2.setPassword(null);
                jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "修改成功", user2);
            }else {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "用户不匹配");
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "系统异常，请联系管理员");
        }
        return jsonResult;
    }

    /**
     * 获取用户
     * @param request
     * @return
     */
    @RequestMapping(value = "/getUserById")
    public JsonResult getUser (HttpServletRequest request) {
        JsonResult jsonResult;
        try {
            Object user = redisUtil.get(request.getHeader("token"));
            if (user == null) {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "用户不存在");
            }else {
                jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "成功", (User) user);
            }
        }catch (Exception e) {
            e.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "系统异常，请联系管理员");
        }
        return jsonResult;
    }

    /**
     * 修改密码
     * @param params
     * @return
     */
    @RequestMapping(value = "/changePassword")
    public JsonResult changePassword (HttpServletRequest request, String params) {
        JsonResult jsonResult;
        try {
            String token = request.getHeader("token");
            Object object = redisUtil.get(token);
            if (object == null) {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "暂未登录账号");
                return jsonResult;
            }
            Map map = JSONObject.parseObject(params, Map.class);
            String oldpass = map.get("oldpass").toString();
            String oldpassword = AesEncryptUtil.desEncrypt(oldpass).toString();
            String pass = map.get("pass").toString();
            String password = AesEncryptUtil.desEncrypt(pass);
            JSONObject jsonObject = (JSONObject) object;
            User user = jsonObject.toJavaObject(User.class);
            if (AesEncryptUtil.encrypt(MD5Utils.MD5(oldpassword)).equals(user.getPassword())) {
                //记录历史密码
                PasswordRecord passwordRecord = new PasswordRecord();
                passwordRecord.setUserId(user.getId());
                passwordRecord.setUserCode(user.getUserCode());
                passwordRecord.setUserName(user.getUserName());
                passwordRecord.setPasswordOld(user.getPassword());
                passwordRecord.setPasswordNew(AesEncryptUtil.encrypt(MD5Utils.MD5(password)));
                passwordRecordService.insert(passwordRecord);
                user.setPassword(AesEncryptUtil.encrypt(MD5Utils.MD5(password)));
                service.updateByPrimaryKeySelective(user);
                redisUtil.del(token);
                redisUtil.set(token, user);
                user.setPassword(null);
                jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "修改成功", user);
            }else {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "旧密码输入错误");
            }
        }catch (Exception e) {
            e.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "系统异常，请联系管理员");
        }
        return jsonResult;
    }

    /**
     * 修改头像
     * @param request
     * @param request,base64string
     * @return
     */
    @RequestMapping(value = "/uploadAvatar", method = RequestMethod.POST)
    public JsonResult uploadAvatar (HttpServletRequest request, String base64string){
        JsonResult jsonResult;
        try {
            String token = request.getHeader("token");
            Object object = redisUtil.get(token);
            if (object == null) {
                jsonResult = new JsonResult(Constants.STATUS_FAIL, "暂未登录账号");
                return jsonResult;
            }
            JSONObject jsonObject = (JSONObject) object;
            User user = jsonObject.toJavaObject(User.class);
            String uuid = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
            //获取到前缀的定位
            int index = base64string.indexOf("base64,")+7;
            String newImage = base64string.substring(index, base64string.length());//去除前缀
            //将去除前缀的图片文本转化为byte流
            BASE64Decoder decoder = new BASE64Decoder();
            try{
                // Base64解码
                byte[] b = decoder.decodeBuffer(newImage);
                for (int i = 0; i < b.length; ++i) {
                    if (b[i] < 0) {// 调整异常数据
                        b[i] += 256;
                    }
                }
                //将byte转换为文件
                // 生成图片路径和文件名
                String pathString =imagePath + uuid;
                File file  = new File(pathString);
                FileOutputStream  out = new FileOutputStream(pathString);
                out.write(b);
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            user.setAvatarUrl(fileUrl+uuid);
            int i = service.updateByPrimaryKeySelective(user);
            redisUtil.del(token);
            redisUtil.set(token, user);
            user.setPassword(null);
            jsonResult = new JsonResult(Constants.STATUS_SUCCESS, "修改成功", user);
        }catch (Exception e){
            e.printStackTrace();
            jsonResult = new JsonResult(Constants.STATUS_ERROR, "系统异常，请联系管理员");
        }
        return jsonResult;
    }
}
